/*!
 * \file TraderAdapter.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief 交易适配器头文件
 * 
 * 本文件定义了交易适配器相关的类和接口，主要包括：
 * - TraderAdapter: 交易适配器核心类，负责与交易接口的交互
 * - TraderAdapterMgr: 交易适配器管理器，负责管理多个交易适配器
 * 
 * 交易适配器是WonderTrader系统中连接交易引擎和具体交易接口的桥梁，
 * 负责处理订单提交、撤单、持仓查询、资金查询等交易相关功能。
 * 同时提供风险控制、交易统计、数据保存等辅助功能。
 */
#pragma once

#include "../Includes/ExecuteDefs.h"
#include "../Includes/FasterDefs.h"
#include "../Includes/ITraderApi.h"
#include "../Share/BoostFile.hpp"
#include "../Share/StdUtils.hpp"

NS_WTP_BEGIN
class WTSVariant;
class ActionPolicyMgr;
class WTSContractInfo;
class WTSCommodityInfo;
class WtLocalExecuter;
class EventNotifier;

class ITrdNotifySink;

/**
 * @class TraderAdapter
 * @brief 交易适配器类
 * 
 * 交易适配器是连接交易引擎和具体交易接口的核心组件，主要功能包括：
 * 1. 交易接口管理：初始化、连接、断开交易接口
 * 2. 订单管理：提交订单、撤销订单、查询订单状态
 * 3. 持仓管理：查询持仓、更新持仓信息
 * 4. 资金管理：查询资金、更新资金信息
 * 5. 风险控制：订单频率控制、撤单频率控制、自成交检测
 * 6. 数据统计：交易统计、订单统计
 * 7. 数据保存：交易日志、订单日志、实时数据保存
 * 8. 事件通知：向上层模块推送交易事件
 */
class TraderAdapter : public ITraderSpi
{
public:
	TraderAdapter(EventNotifier* caster = NULL);
	~TraderAdapter();

	/**
	 * @brief 适配器状态枚举
	 */
	typedef enum tagAdapterState
	{
		AS_NOTLOGIN,		//未登录
		AS_LOGINING,		//正在登录
		AS_LOGINED,			//已登录
		AS_LOGINFAILED,		//登录失败
		AS_POSITION_QRYED,	//持仓已查询
		AS_ORDERS_QRYED,	//订单已查询
		AS_TRADES_QRYED,	//成交已查询
		AS_ALLREADY			//全部就绪
	} AdapterState;

	/**
	 * @brief 持仓项结构体
	 * 
	 * 用于存储某个合约的持仓信息，包括多头和空头的今仓、昨仓数量
	 */
	typedef struct _PosItem
	{
		//多头持仓
		double	l_newvol;		///< 多头今仓数量
		double	l_newavail;		///< 多头今仓可用数量
		double	l_prevol;		///< 多头昨仓数量
		double	l_preavail;		///< 多头昨仓可用数量

		//空头持仓
		double	s_newvol;		///< 空头今仓数量
		double	s_newavail;		///< 空头今仓可用数量
		double	s_prevol;		///< 空头昨仓数量
		double	s_preavail;		///< 空头昨仓可用数量

		_PosItem()
		{
			memset(this, 0, sizeof(_PosItem));
		}

		/**
		 * @brief 获取总持仓量
		 * @param isLong 是否为多头持仓
		 * @return 总持仓量
		 */
		double total_pos(bool isLong = true) const
		{
			if (isLong)
				return l_newvol + l_prevol;
			else
				return s_newvol + s_prevol;
		}

		/**
		 * @brief 获取可用持仓量
		 * @param isLong 是否为多头持仓
		 * @return 可用持仓量
		 */
		double avail_pos(bool isLong = true) const
		{
			if (isLong)
				return l_newavail + l_preavail;
			else
				return s_newavail + s_preavail;
		}

	} PosItem;

	/**
	 * @brief 风险控制参数结构体
	 * 
	 * 用于配置交易风险控制规则，包括订单频率限制和撤单频率限制
	 */
	typedef struct _RiskParams
	{
		uint32_t	_order_times_boundary;		///< 订单次数边界值
		uint32_t	_order_stat_timespan;		///< 订单统计时间跨度(秒)
		uint32_t	_order_total_limits;		///< 订单总数限制

		uint32_t	_cancel_times_boundary;		///< 撤单次数边界值
		uint32_t	_cancel_stat_timespan;		///< 撤单统计时间跨度(秒)
		uint32_t	_cancel_total_limits;		///< 撤单总数限制

		_RiskParams()
		{
			memset(this, 0, sizeof(_RiskParams));
		}
	} RiskParams;

public:
	/**
	 * @brief 初始化交易适配器
	 * @param id 适配器ID
	 * @param params 配置参数
	 * @param bdMgr 基础数据管理器
	 * @param policyMgr 策略管理器
	 * @return 是否初始化成功
	 */
	bool init(const char* id, WTSVariant* params, IBaseDataMgr* bdMgr, ActionPolicyMgr* policyMgr);
	
	/**
	 * @brief 扩展初始化方法
	 * @param id 适配器ID
	 * @param api 交易接口实例
	 * @param bdMgr 基础数据管理器
	 * @param policyMgr 策略管理器
	 * @return 是否初始化成功
	 */
	bool initExt(const char* id, ITraderApi* api, IBaseDataMgr* bdMgr, ActionPolicyMgr* policyMgr);

	/**
	 * @brief 释放资源
	 */
	void release();

	/**
	 * @brief 启动适配器
	 * @return 是否启动成功
	 */
	bool run();

	/**
	 * @brief 获取适配器ID
	 * @return 适配器ID
	 */
	inline const char* id() const{ return _id.c_str(); }

	/**
	 * @brief 获取适配器状态
	 * @return 适配器状态
	 */
	AdapterState state() const{ return _state; }

	/**
	 * @brief 添加交易通知接收器
	 * @param sink 通知接收器
	 */
	void addSink(ITrdNotifySink* sink)
	{
		_sinks.insert(sink);
	}

private:
	/**
	 * @brief 执行委托下单
	 * @param entrust 委托单信息
	 * @return 本地订单ID
	 */
	uint32_t doEntrust(WTSEntrust* entrust);
	
	/**
	 * @brief 执行撤单操作
	 * @param ordInfo 订单信息
	 * @return 是否撤单成功
	 */
	bool	doCancel(WTSOrderInfo* ordInfo);

	/**
	 * @brief 打印持仓信息
	 * @param stdCode 标准合约代码
	 * @param pItem 持仓项
	 */
	inline void	printPosition(const char* stdCode, const PosItem& pItem);

	/**
	 * @brief 获取合约信息
	 * @param stdCode 标准合约代码
	 * @return 合约信息
	 */
	inline WTSContractInfo* getContract(const char* stdCode);
	
	/**
	 * @brief 获取品种信息
	 * @param stdCommID 标准品种ID
	 * @return 品种信息
	 */
	inline WTSCommodityInfo* getCommodify(const char* stdCommID);

	/**
	 * @brief 获取风险控制参数
	 * @param stdCode 标准合约代码
	 * @return 风险控制参数
	 */
	const RiskParams* getRiskParams(const char* stdCode);

	/**
	 * @brief 初始化数据保存功能
	 */
	void initSaveData();

	/**
	 * @brief 记录交易日志
	 * @param localid 本地订单ID
	 * @param stdCode 标准合约代码
	 * @param trdInfo 交易信息
	 */
	inline void	logTrade(uint32_t localid, const char* stdCode, WTSTradeInfo* trdInfo);
	
	/**
	 * @brief 记录订单日志
	 * @param localid 本地订单ID
	 * @param stdCode 标准合约代码
	 * @param ordInfo 订单信息
	 */
	inline void	logOrder(uint32_t localid, const char* stdCode, WTSOrderInfo* ordInfo);

	/**
	 * @brief 保存数据到文件
	 * @param ayFunds 资金数组
	 */
	void	saveData(WTSArray* ayFunds = NULL);

	/**
	 * @brief 更新未完成数量
	 * @param stdCode 标准合约代码
	 * @param qty 数量
	 * @param bOuput 是否输出日志
	 */
	inline void updateUndone(const char* stdCode, double qty, bool bOuput = true);

public:
	/**
	 * @brief 获取持仓数量
	 * @param stdCode 标准合约代码
	 * @param bValidOnly 是否只返回有效持仓
	 * @param flag 持仓标志(1-多头,2-空头,3-净持仓)
	 * @return 持仓数量
	 */
	double getPosition(const char* stdCode, bool bValidOnly, int32_t flag = 3);
	
	/**
	 * @brief 获取订单映射表
	 * @param stdCode 标准合约代码
	 * @return 订单映射表
	 */
	OrderMap* getOrders(const char* stdCode);
	
	/**
	 * @brief 获取未完成数量
	 * @param stdCode 标准合约代码
	 * @return 未完成数量
	 */
	double getUndoneQty(const char* stdCode)
	{
		auto it = _undone_qty.find(stdCode);
		if (it != _undone_qty.end())
			return it->second;

		return 0;
	}

	/**
	 * @brief 开多仓
	 * @param stdCode 标准合约代码
	 * @param price 价格
	 * @param qty 数量
	 * @param flag 标志
	 * @param cInfo 合约信息
	 * @return 本地订单ID
	 */
	uint32_t openLong(const char* stdCode, double price, double qty, int flag, WTSContractInfo* cInfo = NULL);
	
	/**
	 * @brief 开空仓
	 * @param stdCode 标准合约代码
	 * @param price 价格
	 * @param qty 数量
	 * @param flag 标志
	 * @param cInfo 合约信息
	 * @return 本地订单ID
	 */
	uint32_t openShort(const char* stdCode, double price, double qty, int flag, WTSContractInfo* cInfo = NULL);
	
	/**
	 * @brief 平多仓
	 * @param stdCode 标准合约代码
	 * @param price 价格
	 * @param qty 数量
	 * @param isToday 是否平今仓
	 * @param flag 标志
	 * @param cInfo 合约信息
	 * @return 本地订单ID
	 */
	uint32_t closeLong(const char* stdCode, double price, double qty, bool isToday, int flag, WTSContractInfo* cInfo = NULL);
	
	/**
	 * @brief 平空仓
	 * @param stdCode 标准合约代码
	 * @param price 价格
	 * @param qty 数量
	 * @param isToday 是否平今仓
	 * @param flag 标志
	 * @param cInfo 合约信息
	 * @return 本地订单ID
	 */
	uint32_t closeShort(const char* stdCode, double price, double qty, bool isToday, int flag, WTSContractInfo* cInfo = NULL);
	
	/**
	 * @brief 买入操作
	 * @param stdCode 标准合约代码
	 * @param price 价格
	 * @param qty 数量
	 * @param flag 标志
	 * @param bForceClose 是否强制平仓
	 * @param cInfo 合约信息
	 * @return 订单ID列表
	 */
	OrderIDs buy(const char* stdCode, double price, double qty, int flag, bool bForceClose, WTSContractInfo* cInfo = NULL);
	
	/**
	 * @brief 卖出操作
	 * @param stdCode 标准合约代码
	 * @param price 价格
	 * @param qty 数量
	 * @param flag 标志
	 * @param bForceClose 是否强制平仓
	 * @param cInfo 合约信息
	 * @return 订单ID列表
	 */
	OrderIDs sell(const char* stdCode, double price, double qty, int flag, bool bForceClose, WTSContractInfo* cInfo = NULL);
	
	/**
	 * @brief 撤销指定订单
	 * @param localid 本地订单ID
	 * @return 是否撤单成功
	 */
	bool	cancel(uint32_t localid);
	
	/**
	 * @brief 撤销指定合约的订单
	 * @param stdCode 标准合约代码
	 * @param isBuy 是否为买单
	 * @param qty 撤单数量(0表示全部撤销)
	 * @return 撤销的订单ID列表
	 */
	OrderIDs cancel(const char* stdCode, bool isBuy, double qty = 0);

	/**
	 * @brief 检查合约是否允许交易
	 * @param stdCode 标准合约代码
	 * @return 是否允许交易
	 */
	inline bool	isTradeEnabled(const char* stdCode) const;

	/**
	 * @brief 检查撤单限制
	 * @param stdCode 标准合约代码
	 * @return 是否通过撤单限制检查
	 */
	bool	checkCancelLimits(const char* stdCode);
	
	/**
	 * @brief 检查订单限制
	 * @param stdCode 标准合约代码
	 * @return 是否通过订单限制检查
	 */
	bool	checkOrderLimits(const char* stdCode);

	/**
	 * @brief 检查自成交
	 * @param stdCode 标准合约代码
	 * @param tInfo 交易信息
	 * @return 是否为自成交
	 */
	bool	checkSelfMatch(const char* stdCode, WTSTradeInfo* tInfo);

	/**
	 * @brief 判断是否为自成交合约
	 * @param stdCode 标准合约代码
	 * @return 是否为自成交合约
	 */
	inline	bool isSelfMatched(const char* stdCode)
	{
		auto it = _self_matches.find(stdCode);
		return it != _self_matches.end();
	}

public:
	//////////////////////////////////////////////////////////////////////////
	//ITraderSpi接口实现
	
	/**
	 * @brief 处理交易事件
	 * @param e 交易事件类型
	 * @param ec 错误码
	 */
	virtual void handleEvent(WTSTraderEvent e, int32_t ec) override;

	/**
	 * @brief 登录结果回调
	 * @param bSucc 是否登录成功
	 * @param msg 登录消息
	 * @param tradingdate 交易日期
	 */
	virtual void onLoginResult(bool bSucc, const char* msg, uint32_t tradingdate) override;

	/**
	 * @brief 登出回调
	 */
	virtual void onLogout() override;

	/**
	 * @brief 委托响应回调
	 * @param entrust 委托信息
	 * @param err 错误信息
	 */
	virtual void onRspEntrust(WTSEntrust* entrust, WTSError *err) override;

	/**
	 * @brief 资金响应回调
	 * @param ayAccounts 资金账户数组
	 */
	virtual void onRspAccount(WTSArray* ayAccounts) override;

	/**
	 * @brief 持仓响应回调
	 * @param ayPositions 持仓数组
	 */
	virtual void onRspPosition(const WTSArray* ayPositions) override;

	/**
	 * @brief 订单响应回调
	 * @param ayOrders 订单数组
	 */
	virtual void onRspOrders(const WTSArray* ayOrders) override;

	/**
	 * @brief 成交响应回调
	 * @param ayTrades 成交数组
	 */
	virtual void onRspTrades(const WTSArray* ayTrades) override;

	/**
	 * @brief 订单推送回调
	 * @param orderInfo 订单信息
	 */
	virtual void onPushOrder(WTSOrderInfo* orderInfo) override;

	/**
	 * @brief 成交推送回调
	 * @param tradeRecord 成交记录
	 */
	virtual void onPushTrade(WTSTradeInfo* tradeRecord) override;

	/**
	 * @brief 交易错误回调
	 * @param err 错误信息
	 */
	virtual void onTraderError(WTSError* err) override;

	/**
	 * @brief 获取基础数据管理器
	 * @return 基础数据管理器
	 */
	virtual IBaseDataMgr* getBaseDataMgr() override;

	/**
	 * @brief 处理交易日志
	 * @param ll 日志级别
	 * @param message 日志消息
	 */
	virtual void handleTraderLog(WTSLogLevel ll, const char* message) override;

private:
	WTSVariant*			_cfg;				///< 配置信息
	std::string			_id;				///< 适配器ID
	std::string			_order_pattern;		///< 订单模式

	uint32_t			_trading_day;		///< 交易日

	ITraderApi*			_trader_api;		///< 交易接口
	FuncDeleteTrader	_remover;			///< 删除交易接口函数
	AdapterState		_state;				///< 适配器状态

	EventNotifier*		_notifier;			///< 事件通知器

	faster_hashset<ITrdNotifySink*>	_sinks;	///< 交易通知接收器集合

	IBaseDataMgr*		_bd_mgr;			///< 基础数据管理器
	ActionPolicyMgr*	_policy_mgr;		///< 策略管理器

	faster_hashmap<LongKey, PosItem> _positions;	///< 持仓映射表

	StdUniqueMutex _mtx_orders;				///< 订单互斥锁
	OrderMap*		_orders;				///< 订单映射表
	faster_hashset<LongKey> _orderids;		///< 订单ID集合，主要用于标记没有成交回报的订单

	faster_hashmap<LongKey, std::string>		_trade_refs;	///< 用于记录成交单与订单的匹配
	faster_hashset<LongKey>						_self_matches;	///< 自成交的合约

	faster_hashmap<LongKey, double> _undone_qty;	///< 未完成数量

	typedef WTSHashMap<LongKey>	TradeStatMap;
	TradeStatMap*	_stat_map;				///< 统计数据

	//风险控制相关时间缓存的数据,主要是为了控制瞬时的高频交易用的
	typedef std::vector<uint64_t> TimeCacheList;
	typedef faster_hashmap<LongKey, TimeCacheList> CodeTimeCacheMap;
	CodeTimeCacheMap	_order_time_cache;	///< 下单时间缓存
	CodeTimeCacheMap	_cancel_time_cache;	///< 撤单时间缓存

	//风险控制相关,客户端配到的排除代码
	faster_hashset<LongKey>	_exclude_codes;	///< 排除的合约代码
	
	typedef faster_hashmap<LongKey, RiskParams>	RiskParamsMap;
	RiskParamsMap	_risk_params_map;		///< 风险参数映射表
	bool			_risk_mon_enabled;		///< 是否启用风险监控

	bool			_save_data;				///< 是否保存交易数据
	BoostFilePtr	_trades_log;			///< 成交数据日志
	BoostFilePtr	_orders_log;			///< 订单数据日志
	std::string		_rt_data_file;			///< 实时数据文件
};

typedef std::shared_ptr<TraderAdapter>				TraderAdapterPtr;
typedef faster_hashmap<std::string, TraderAdapterPtr>	TraderAdapterMap;


//////////////////////////////////////////////////////////////////////////
//TraderAdapterMgr

/**
 * @class TraderAdapterMgr
 * @brief 交易适配器管理器
 * 
 * 负责管理多个交易适配器实例，提供统一的适配器管理接口：
 * 1. 适配器注册和获取
 * 2. 适配器生命周期管理
 * 3. 适配器运行状态管理
 */
class TraderAdapterMgr : private boost::noncopyable
{
public:
	/**
	 * @brief 释放所有适配器资源
	 */
	void	release();

	/**
	 * @brief 启动所有适配器
	 */
	void	run();

	/**
	 * @brief 获取所有适配器
	 * @return 适配器映射表
	 */
	const TraderAdapterMap& getAdapters() const { return _adapters; }

	/**
	 * @brief 获取指定名称的适配器
	 * @param tname 适配器名称
	 * @return 适配器指针
	 */
	TraderAdapterPtr getAdapter(const char* tname);

	/**
	 * @brief 添加适配器
	 * @param tname 适配器名称
	 * @param adapter 适配器指针
	 * @return 是否添加成功
	 */
	bool	addAdapter(const char* tname, TraderAdapterPtr& adapter);

private:
	TraderAdapterMap	_adapters;	///< 适配器映射表
};

NS_WTP_END
